如何在c中交换链表节点

时间:2016-06-20 01:07:45

标签: c struct

我试图交换两个链表,我的排序功能不起作用。如何交换整个节点。我试图做的是交换整个列表,而不是交换它的成员。

import UIKit
import CoreData

class AddEditViewController: UIViewController, NSFetchedResultsControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var item : Item? = nil

@IBOutlet weak var itemName: UITextField!
@IBOutlet weak var itemNote: UITextField!
@IBOutlet weak var hoursPlayed: UITextField!
@IBOutlet weak var imageHolder: UIImageView!

let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

override func viewDidLoad() {
    super.viewDidLoad()

    if item != nil {
        itemName.text = item?.name
        itemNote.text = item?.note
        hoursPlayed.text = item?.hoursPlayed
        imageHolder.image = UIImage(data: (item?.image)!)
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func AddImage(sender: AnyObject) {
    let pickerController = UIImagePickerController()
    pickerController.delegate = self
    pickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    pickerController.allowsEditing = true

    self.presentViewController(pickerController, animated: true, completion: nil)
}

@IBAction func addImageFromCamera(sender: AnyObject) {
    let pickerController = UIImagePickerController()
    pickerController.delegate = self
    pickerController.sourceType = UIImagePickerControllerSourceType.Camera
    pickerController.allowsEditing = true

    self.presentViewController(pickerController, animated: true, completion: nil)
}

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
    self.dismissViewControllerAnimated(true, completion: nil)

    self.imageHolder.image = image
}

@IBAction func saveTapped(sender: AnyObject) {

    var nameMissing = ""

    if itemName == nil {
        nameMissing = "name"
        print("item missing")
    }
    else if itemNote == nil {
        nameMissing = "note"
        print("note missing")
    }
    else if hoursPlayed == nil {
        nameMissing = "hours played"
        print("hours played missing")
    }
    else if imageHolder == nil {
        nameMissing = "image"
        print("image missing")
    }

    if (itemName == nil || itemNote == nil || hoursPlayed == nil || imageHolder == nil) {
        let missingDetailsAlertController = UIAlertController(title: "Alert", message: "Complete field for \(nameMissing).", preferredStyle: UIAlertControllerStyle.Alert)
        missingDetailsAlertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
        self.presentViewController(missingDetailsAlertController, animated: true, completion: nil)
        return
    }

    if(item != nil) {
        editItem()
    } else {
        createNewItem()
    }
    dismissViewController()
}

@IBAction func cancelTapped(sender: AnyObject) {
    dismissViewController()
}

func dismissViewController() {
    navigationController?.popViewControllerAnimated(true)
}

func createNewItem() {
    let entityDescription = NSEntityDescription.entityForName("item", inManagedObjectContext: moc)

    let item = Item(entity: entityDescription!, insertIntoManagedObjectContext: moc)

    item.name = itemName.text
    item.note = itemNote.text
    item.hoursPlayed = hoursPlayed.text
    item.image = UIImagePNGRepresentation(imageHolder.image!)

    do {
        try moc.save()
    } catch {
        print("Create Save Failed.")
        return
    }
}

func editItem() {
    item?.name = itemName.text
    item?.note = itemNote.text
    item?.hoursPlayed = hoursPlayed.text
    item!.image = UIImagePNGRepresentation(imageHolder.image!)

    do {
        try moc.save()
    } catch {
        print("Edit Save Failed.")
        return
    }
}
}

1 个答案:

答案 0 :(得分:1)

您的交换函数混合了节点数据和节点指针,因此数据(包括与next指针相关的数据)正在“交换”......

...这种混淆可能导致内存泄漏和节点链中断。如果你很幸运,链条将保持不变,但你将交换一个完整的小节而不是两个节点。

要交换节点数据,请考虑(这是未经测试的代码):

// ugly, but should work
typedef struct node {
  char* first_name;
  char* last_name;
  struct node* next;
} person;

void swap(person* a, person* b) {
  person tmp;
  tmp.first_name = a->first_name;
  tmp.last_name = a->last_name;
  a->first_name = b->first_name;
  a->last_name = b->last_name;
  b->first_name = tmp.first_name;
  b->last_name = tmp.last_name;
}

或者这个(不那么丑陋,更容易维护):

typedef struct {
  char* first_name;
  char* last_name;

} person_s;

typedef struct person_nd person_nd;

struct person_nd {
  person_s data;
  person_nd* next;
};

void swap2(person_nd* a, person_nd* b) {
  person_s tmp;
  tmp = a->data;
  a->data = b->data;
  b->data = tmp;
}

这些都是丑陋的解决方案。正确的方法是将数据保持原样并交换节点的位置。

要求我们了解有关节点列表结构的更多信息,特别是引用节点的指针的地址。

另一方面,这种类型的解决方案与数据无关,因此对数据结构的更新不应要求重写实现。

即。 (这肯定会失败,但它应该证明这个概念):

void swap3(person_nd** a, person_nd** b) {
  person_nd* tmp = *a;
  // swap the position in the tree.
  *a = *b;
  *b = tmp;
  // swap the "forward" branches
  tmp = (*a)->next;
  (*a)->next = (*b)->next;
  (*b)->next = tmp;
}